package com.xy.servicemanage.request;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.google.gson.GsonBuilder;
import com.xy.common.util.Configure;
import com.xy.manage.service.TinfoService;
import com.xy.servicemanage.action.TservicesAction;
import com.xy.servicemanage.model.ServiceSetting;
import com.xy.servicemanage.model.Treqparams;
import com.xy.servicemanage.model.Tresparams;
import com.xy.servicemanage.model.Tservicecustomer;
import com.xy.servicemanage.model.Tservices;

public class AppRequestHelper {
	private static String errorCode = "errorCode";
	private static String errorMeesage = "errorMessage";
	private static String serviceId = "CLWID";
	private static String custId = "custId";
	private static String signMsg = "signmsg";
	private static String sendTime = "ts";
	private static String Total = "total";
	//违章查询验证输入接口
	private static String VAL_BR_input = "10013";
	private static final Logger log = LoggerFactory
			.getLogger(AppRequestHelper.class);
	private static List<String> sessionList=new ArrayList<String>();

	public static String processRequest(HttpServletRequest request) {
		try {
			Map<String, Object> vmap = null;
			boolean isMultipart = ServletFileUpload.isMultipartContent(request);
			if (isMultipart) {
				MultipartHttpServletRequest mh = (MultipartHttpServletRequest) request;
				vmap = getReqValues(mh);
				Map<String,MultipartFile> m=mh.getFileMap();
				Set<String> set=m.keySet();
				for(String name:set){
					MultipartFile mf= 	m.get(name);
					vmap.put(name, mf.getBytes());
				}

			} else {
				vmap = getReqValues(request);
			}

			Object sid = vmap.get(serviceId) ;
			Object cid = vmap.get(custId);
			if (sid == null || sid.toString().trim().equals("")) {
				return getError("10001", "serviceId is null");
			}
			if (cid == null || cid.toString().trim().equals("")) {
				return getError("10002", "custId is null");
			}

			Tservicecustomer cust = ServiceSetting.getInstance()
					.getServicecustomerByCustId(cid.toString());
			if (cust == null) {
				return getError("10003", "customer not valid");
			}

			Tservices service = ServiceSetting.getInstance()
					.getServiceByServiceId(sid.toString());
			if (service == null) {
				return getError("10004", "service not found");
			}
			if (cust.getServiceList().indexOf(sid.toString()) == -1) {
				return getError("10004", "service not allow");
			}
			if (!validRequest(vmap, service)) {
				return getError("10005", "request parameter not validate");
			}
			if (!validSign(vmap, cust)) {
				return getError("10006", "signmsg not validate");
			}
			if (!Configure.getProperty("serviceType").equals("dev")) {
				Object signmsg = vmap.get("signmsg");
				if (sessionList.contains(signmsg)) {
					return getError("10009", "Do not submit the same request!");
				}
				sessionList.add(signmsg.toString());
				if (sessionList.size() > 10000) {
					sessionList.remove(0);
				}
			}
			
			try {
				Object ret = null;
				Object serviceid = vmap.get(TservicesAction.serviceId);

				if ("1030".equals(serviceid)) {
					// 发送短信验证码
					String code = VerifyCodeHelper.sendMessage(vmap);
					List<Tresparams> resList = ServiceSetting.getInstance().getResparamBySid(service.getSid());
					Map m = new HashMap();
					m.put(resList.get(0).getResid(), code);
					List<Map> l = new ArrayList<Map>();
					l.add(m);
					ret = l;
				} else if ("1019".equals(serviceid) && "0".equals(vmap.get("LoginType"))) {
					// 短信验证码登陆
					int r = VerifyCodeHelper.verify(vmap);
					List<Tresparams> resList = ServiceSetting.getInstance().getResparamBySid(service.getSid());
					Map m = new HashMap();
					m.put(resList.get(0).getResid(), r);
					List<Map> l = new ArrayList<Map>();
					l.add(m);
					ret = l;
				} else if ("1028".equals(serviceid)) {
					Tservices testService =  ServiceSetting.getInstance().getServiceByServiceId(VAL_BR_input);
					ret = ServiceEnginer.getInstance().process(testService, vmap);
					List<Map> list = (List<Map>) ret;
					for (Map m : list) {
						if (null != m.get(Total) && ((Integer) m.get(Total)) == 0) {
							String str = new GsonBuilder().create().toJson(ret);
							StringBuffer sb = new StringBuffer();
							sb.append("{\"returnCode\":\"1\",\"returnMessage\":\"success\",\"result\":[{\"result\":\"输入错误\"}]}");
							return sb.toString();
						}
					}
					ret = ServiceEnginer.getInstance().process(service, vmap);
				} else {
					ret = ServiceEnginer.getInstance().process(service, vmap);
				}
				String str = new GsonBuilder().create().toJson(ret);
				StringBuffer sb = new StringBuffer();
				sb.append("{\"returnCode\":\"1\",\"returnMessage\":\"success\",\"result\":");
				sb.append(str).append("}");
				return sb.toString();
			} catch (Exception e) {
				log.error("processRequest", e);
				return getError("10007", e.getLocalizedMessage());
			}
		} catch (Exception e) {
			log.error("processRequest", e);
			return getError("10008", e.getLocalizedMessage());
		}
	}

	private static String getError(String code, String msg)  {
		Map<String, Object> m = new HashMap<String, Object>();
		m.put(returnCode, code);
		m.put(returnMessage, msg);
		m.put(result, new ArrayList());
		return new GsonBuilder().create().toJson(m);
	}
	public static String returnCode = "returnCode";
	public static String returnMessage = "returnMessage";
	public static String result = "result";

	private static Map getReqValues(HttpServletRequest request) {
		Map<String, String> vmap = new HashMap<String, String>();
		Enumeration<String> e = request.getParameterNames();
		while (e.hasMoreElements()) {
			String name = e.nextElement();
			String value1 = request.getParameter(name);
			String value = value1;
			try {
				value = new String(value1.getBytes("ISO8859-1"), "UTF-8");
			} catch (UnsupportedEncodingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			vmap.put(name, value);
		}
        vmap.put("sourceip", request.getRemoteAddr());
		return vmap;
	}

	private static boolean validSign(Map<String, Object> values,
			Tservicecustomer cust) {
		if(Configure.getProperty("serviceType").equals("dev"))
			return true;
		Object sign = values.get(signMsg);
		if (sign == null || "".equals(sign)) {
			return false;
		}

		Object sendtime = values.get(sendTime);
		String key = cust.getPrikey();
		String t = key + sendtime;
		String s=crypt(t);
		if(!sign.equals(s)){
			log.info("Sign msg not valid--> source:"
					+ sign + ", md5:" +s+"("+t+")");
			return false;
		}
		return true;

	}

	private static boolean validRequest(Map<String, Object> values,
			Tservices service) {
		List<Treqparams> list = ServiceSetting.getInstance().getReqparamBySid(
				service.getSid());
		if(list==null)return true;
		for (Treqparams r : list) {
			if ("1".equals(r.getIsMustin())) {
				Object v = values.get(r.getReqid());
				if (v == null || "".equals(v)) {
					log.info("parameter can not be null:"
							+ service.getServiceId() + "->" + r.getReqid());
					return false;
				}
				if (r.getReqlen() != null && !"".equals(r.getReqlen())) {
					int l = Integer.valueOf(r.getReqlen());
					if (l < v.toString().length()) {
						log.info("parameter max length is:" + r.getReqlen()
								+ " , and input length is:"
								+ service.getServiceId() + "->" + r.getReqid());
						return false;
					}
				}
			}
		}
		return true;
	}

	public static String crypt(String str) {
		if (str == null || str.length() == 0) {
			throw new IllegalArgumentException(
					"String to encript cannot be null or zero length");
		}

		StringBuffer hexString = new StringBuffer();

		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(str.getBytes());
			byte[] hash = md.digest();

			for (int i = 0; i < hash.length; i++) {
				if ((0xff & hash[i]) < 0x10) {
					hexString.append("0"
							+ Integer.toHexString((0xFF & hash[i])));
				} else {
					hexString.append(Integer.toHexString(0xFF & hash[i]));
				}
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		return hexString.toString();
	}
	
public static void main(String args[]){
	String key="OS6IQ0OIE0I1R3FG3WGNUE3E3";
	long t=System.currentTimeMillis();
	String m=key+t;
	String s=crypt(m);
	System.out.println( "ts:"+t);
	System.out.println( "signmsg:"+s);
}
	 
}
